﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
using SKDB_Matcher.SQL.Database;
using System.Threading;

namespace SKDB_Matcher
{
    public partial class Form1 : Form
    {
        const int KEY_START_ID = 2;

        DataSet m_SourceSet;
        DataSet m_TargetSet;
        DataTable[] m_RelationTables;

        List<CMatchPage> m_MatchPages;
      
        int m_SelectedTable;

        string m_SourceDBName = "Sportsworld";
        string m_TargetDBName = "House of Sports";

        public Form1()
        {
            InitializeComponent();
            CConsole.init(this.lboConsole);

            SetupConnection(true);
            CMatcher.CreateInstance();

            //LoadDataBases();
        }

        private void LoadSourceSet()
        {
            SourceBox.Text = "Source - " + m_SourceDBName;

            m_SourceSet = CDatabaseHelper.LoadDataSet(m_SourceDBName);

            LoadSourceComboBoxItems();

            CDatabaseHelper.setDataBaseTree(m_SourceSet, tvSourceTree);

            labelSourceSelect.Visible = false;
            btSourceSelect.Visible = false;

            cmbSourceTables.Visible = true;
            tvSourceColumns.Visible = true;
            tvSourceRelations.Visible = true;
            tvSourceTree.Visible = true;
            RelationLabel.Visible = true;
            SetupMatcher();
        }

        private void LoadTargetSet()
        {
            TargetBox.Text = "Target - " + m_TargetDBName;

            m_MatchPages = new List<CMatchPage>();
            m_TargetSet = CDatabaseHelper.LoadDataSet(m_TargetDBName);

            LoadDestinationTabPages();

            CDatabaseHelper.setDataBaseTree(m_TargetSet, tvDestinationTree);

            tcDestination.Visible = true;

            labelTargetSelect.Visible = false;
            btTargetSelect.Visible = false;

            SetupMatcher();
        }

        private void SetupMatcher()
        {
            if (m_TargetSet != null && m_SourceSet != null)
            {
                CMatcher.GetInstance().Reset(m_SourceSet, m_TargetSet);
                btnAutoMatch.Enabled = true;
            }
        }

        void LoadDestinationTabPages()
        {
            foreach (CMatchPage Page in m_MatchPages)
            {
                Page.Dispose();
            }
            m_MatchPages.Clear();
            tcDestination.TabPages.Clear();

            foreach (DataTable table in m_TargetSet.Tables)
            {               
                TabPage newPage = new TabPage(table.TableName);
                CMatchPage matchPage = new CMatchPage();
                matchPage.SetDestinationTable(table);
                matchPage.Dock = DockStyle.Fill;
                matchPage.Parent = newPage;                                
                tcDestination.TabPages.Add(newPage);
                m_MatchPages.Add(matchPage);
            }
        }

        public void LoadSourceComboBoxItems()
        {
            cmbSourceTables.Items.Clear();
            foreach (DataTable Table in m_SourceSet.Tables)
            {
                cmbSourceTables.Items.Add(Table.TableName);
            }
            cmbSourceTables.SelectedIndex = 0;
        }

        private void SourceTree_AfterSelect(object sender, TreeViewEventArgs e)
        {
            int selection = (int)e.Node.Tag;
            if (e.Node.Parent != null)
            {
                int parentSelection = (int)e.Node.Parent.Tag;
                //m_SourceSet.Tables[ParentSelection].Columns[Selection];
            }               
        }

        private void cmbTables_SelectedIndexChanged(object sender, EventArgs e)
        {
            int KeyID = KEY_START_ID;
            int ColID = 0;
            tvSourceColumns.Nodes.Clear();
            m_SelectedTable = cmbSourceTables.SelectedIndex;
            foreach (DataColumn Col in m_SourceSet.Tables[m_SelectedTable].Columns)
            {
                TreeNode Node = new TreeNode(Col.ColumnName);
                Node.Tag = ColID;
                Node.ImageIndex = 1;
                foreach (DataRelation Relation in m_SourceSet.Tables[m_SelectedTable].ParentRelations)
                    foreach (DataColumn ChildCol in Relation.ChildColumns)
                        if (Col.Equals(ChildCol))
                        {
                            Node.Text = Node.Text;// +KeyID;
                            Node.ImageIndex = KeyID++;
                        }

                tvSourceColumns.Nodes.Add(Node);
                ColID++;
            }
            FindRelations();
        }

         // TODO
        // Richtig durchnummerieren
        private void FindRelations()
        {
            m_RelationTables = null;
            int KeyID = KEY_START_ID;
            tvSourceRelations.Nodes.Clear();
            m_RelationTables = new DataTable[m_SourceSet.Tables[m_SelectedTable].ParentRelations.Count];
            int tableCount = 0;
            foreach (DataRelation Relation in m_SourceSet.Tables[m_SelectedTable].ParentRelations)
            {
                TreeNode tableNode = new TreeNode(Relation.ParentTable.TableName);
                tableNode.Tag = tableCount;
                m_RelationTables[tableCount] = Relation.ParentTable;
                int colCount = 0;
                foreach (DataColumn col in Relation.ParentTable.Columns)
                {
                    TreeNode colNode = new TreeNode(col.ColumnName + " " + col.DataType.Name);
                    colNode.ImageIndex = 1;
                    colNode.Tag = colCount;
                    foreach (DataColumn pCol in Relation.ParentColumns)
                        if (col.Equals(pCol))
                        {
                            colNode.Text = colNode.Text;// +KeyID;
                            colNode.ImageIndex = KeyID++;
                        }

                    tableNode.Nodes.Add(colNode);
                    colCount++;
                }
                tvSourceRelations.Nodes.Add(tableNode);
                tableCount++;
            }
            tvSourceRelations.ExpandAll();
        }

        private void tvSourceRelations_ItemDrag(object sender, ItemDragEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                TreeNode draggedNode = ((TreeNode)e.Item);
                if (draggedNode.Parent != null)
                {
                    int tableID = (int)draggedNode.Parent.Tag;
                    int colID = (int)draggedNode.Tag;
                    DataColumn draggedCol = m_RelationTables[tableID].Columns[colID];
                    DoDragDrop(draggedCol, DragDropEffects.Copy);
                }
            }
        }

       private void tvSourceColumns_ItemDrag(object sender, ItemDragEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                TreeNode draggedNode = ((TreeNode)e.Item);
                int ColID = (int)draggedNode.Tag;
                DataColumn draggedCol = m_SourceSet.Tables[m_SelectedTable].Columns[ColID];
                DoDragDrop(draggedCol, DragDropEffects.Copy);

            }
        }

       private Boolean calculating = false;
       private void btnAutoMatch_Click(object sender, EventArgs e)
       {
           new Thread(_match).Start();
       }

       private void _match()
       {
           startCalculatingLabel();
           CMatcher.GetInstance().Match();
           if (CMatcher.GetInstance().SuccesfullMatching)
           {
               int page = 0;
               foreach (DataTable Table in m_TargetSet.Tables)
               {
                   foreach (DataColumn Column in Table.Columns)
                   {
                       float Matching = 0.0f;
                       DataColumn MatchCol = CMatcher.GetInstance().GetBestMatch(Column, ref Matching);
                       m_MatchPages[page].SetRowValue(Column, MatchCol, Matching);
                   }
                   page++;
               }
           }
           stopCalculatingLabel();
       }

       private void SetupConnection(Boolean First = false)
       {
           CDBSetupDlg dbDlg = new CDBSetupDlg();
           dbDlg.Init("config.xml");
           if (dbDlg.ShowDialog(First) == System.Windows.Forms.DialogResult.OK)
           {
               dbDlg.BindConnectionSettings();
           }
       }

       private void algorithmenGewichtungToolStripMenuItem_Click(object sender, EventArgs e)
       {
           CAlgorithmWeightDlg WeightDlg = new CAlgorithmWeightDlg();
           if (WeightDlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
           {
               //
           }
       }

       private void quellschemaAuswählenToolStripMenuItem_Click(object sender, EventArgs e)
       {
           CChooseDatabase dbDlg = new CChooseDatabase();
           dbDlg.DatabaseName = m_SourceDBName;
           if (dbDlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
           {
               this.m_SourceDBName = dbDlg.DatabaseName;
               LoadSourceSet();
           }
       }

       private void zielschemaAuswählenToolStripMenuItem1_Click(object sender, EventArgs e)
       {
           CChooseDatabase dbDlg = new CChooseDatabase();
           dbDlg.DatabaseName = m_TargetDBName;
           if (dbDlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
           {
               this.m_TargetDBName = dbDlg.DatabaseName;
               LoadTargetSet();
           }
       }

       private void toolStripMenuItem1_Click(object sender, EventArgs e)
       {
           SetupConnection();
       }

       private void datenbankverbindungToolStripMenuItem_Click(object sender, EventArgs e)
       {
           
       }

        private void startCalculatingLabel()
       {
           if (statusStrip1.InvokeRequired)
           {
               statusStrip1.Invoke(new MethodInvoker(() => { startCalculatingLabel(); }));
           }
           else
           {
               tSStatus.Text = "Calculating";
               calculating = true;
           }
       }

       private void timer1_Tick(object sender, EventArgs e)
       {
           if (calculating)
           {
               tSStatus.Text = tSStatus.Text + '.';
               if (tSStatus.Text.EndsWith("...."))
                   tSStatus.Text = "Calculating";
           }
       }

       private void stopCalculatingLabel()
       {
           if (statusStrip1.InvokeRequired)
           {
               statusStrip1.Invoke(new MethodInvoker(() => { stopCalculatingLabel(); }));
            }
           else
           {
               tSStatus.Text = "";
               calculating = false;
           }
       }
    }
}
